from flask import render_template, redirect, url_for, flash, request, jsonify
from flask_login import login_required, current_user
from app import db
from app.main import bp
from app.models import Weight, Meal, Exercise
from datetime import datetime, date, timedelta
import json
from werkzeug.security import generate_password_hash, check_password_hash

@bp.route('/')
@bp.route('/index')
def index():
    return render_template('index.html', title='首页')

@bp.route('/weight', methods=['GET'])
@login_required
def weight_records():
    # 获取查询参数
    page = request.args.get('page', 1, type=int)
    per_page = request.args.get('per_page', 10, type=int)
    start_date = request.args.get('start_date', '')
    end_date = request.args.get('end_date', '')
    sort = request.args.get('sort', 'record_date')
    order = request.args.get('order', 'desc')
    
    # 构建基础查询
    query = Weight.query.filter_by(user_id=current_user.id)
    
    # 日期范围过滤
    if start_date:
        try:
            start = datetime.strptime(start_date, '%Y-%m-%d').date()
            query = query.filter(Weight.record_date >= start)
        except ValueError:
            flash('开始日期格式无效', 'warning')
    
    if end_date:
        try:
            end = datetime.strptime(end_date, '%Y-%m-%d').date()
            query = query.filter(Weight.record_date <= end)
        except ValueError:
            flash('结束日期格式无效', 'warning')
    
    # 排序
    if sort == 'weight':
        query = query.order_by(Weight.weight.desc() if order == 'desc' else Weight.weight.asc())
    else:  # 默认按记录日期排序
        query = query.order_by(Weight.record_date.desc() if order == 'desc' else Weight.record_date.asc())
    
    # 执行分页查询
    weights = query.paginate(page=page, per_page=per_page)
    
    return render_template('weight/records.html', 
                         weights=weights,
                         start_date=start_date,
                         end_date=end_date,
                         sort=sort,
                         order=order,
                         per_page=per_page)

@bp.route('/weight/add', methods=['GET', 'POST'])
@login_required
def add_weight():
    if request.method == 'POST':
        try:
            weight = float(request.form['weight'])
            record_date = datetime.strptime(request.form['record_date'], '%Y-%m-%d').date()
            note = request.form.get('note', '')

            if weight <= 0:
                flash('体重必须大于0', 'danger')
                return redirect(url_for('main.add_weight'))

            # 检查是否已存在同一天的记录
            existing_record = Weight.query.filter_by(
                user_id=current_user.id,
                record_date=record_date
            ).first()

            if existing_record:
                existing_record.weight = weight
                existing_record.note = note
                flash('更新了已存在的记录', 'info')
            else:
                weight_record = Weight(
                    user_id=current_user.id,
                    weight=weight,
                    record_date=record_date,
                    note=note
                )
                db.session.add(weight_record)
            
            db.session.commit()
            flash('体重记录已保存', 'success')
            return redirect(url_for('main.weight_records'))
            
        except ValueError:
            flash('请输入有效的体重数值', 'danger')
        except Exception as e:
            flash('保存失败，请重试', 'danger')
    
    # 为日期输入框设置默认值为今天
    today = date.today().strftime('%Y-%m-%d')
    return render_template('weight/add.html', today=today)

@bp.route('/weight/<int:id>/delete', methods=['POST'])
@login_required
def delete_weight(id):
    weight = Weight.query.get_or_404(id)
    if weight.user_id != current_user.id:
        flash('无权限删除此记录', 'danger')
        return redirect(url_for('main.weight_records'))
    
    db.session.delete(weight)
    db.session.commit()
    flash('记录已删除', 'success')
    return redirect(url_for('main.weight_records'))

@bp.route('/weight/chart-data')
@login_required
def weight_chart_data():
    days = request.args.get('days', 30, type=int)
    weights = Weight.query.filter_by(user_id=current_user.id)\
        .order_by(Weight.record_date.asc())\
        .all()
    
    data = [{
        'date': weight.record_date.strftime('%Y-%m-%d'),
        'weight': weight.weight
    } for weight in weights]
    
    return jsonify(data)

@bp.route('/meal', methods=['GET'])
@login_required
def meal_records():
    page = request.args.get('page', 1, type=int)
    per_page = request.args.get('per_page', 10, type=int)
    start_date = request.args.get('start_date', '')
    end_date = request.args.get('end_date', '')
    meal_type = request.args.get('meal_type', '')
    sort = request.args.get('sort', 'meal_date')
    order = request.args.get('order', 'desc')
    
    query = Meal.query.filter_by(user_id=current_user.id)
    
    if start_date:
        try:
            start = datetime.strptime(start_date, '%Y-%m-%d').date()
            query = query.filter(Meal.meal_date >= start)
        except ValueError:
            flash('开始日期格式无效', 'warning')
    
    if end_date:
        try:
            end = datetime.strptime(end_date, '%Y-%m-%d').date()
            query = query.filter(Meal.meal_date <= end)
        except ValueError:
            flash('结束日期格式无效', 'warning')
    
    if meal_type:
        query = query.filter(Meal.meal_type == meal_type)
    
    if sort == 'calories':
        query = query.order_by(Meal.calories.desc() if order == 'desc' else Meal.calories.asc())
    else:
        query = query.order_by(
            Meal.meal_date.desc() if order == 'desc' else Meal.meal_date.asc(),
            Meal.meal_time.desc() if order == 'desc' else Meal.meal_time.asc()
        )
    
    meals = query.paginate(page=page, per_page=per_page)
    
    return render_template('meal/records.html',
                         meals=meals,
                         start_date=start_date,
                         end_date=end_date,
                         meal_type=meal_type,
                         sort=sort,
                         order=order,
                         per_page=per_page)

@bp.route('/meal/add', methods=['GET', 'POST'])
@login_required
def add_meal():
    if request.method == 'POST':
        try:
            meal_type = request.form['meal_type']
            food_name = request.form['food_name']
            calories = int(request.form['calories']) if request.form['calories'] else None
            protein = float(request.form['protein']) if request.form['protein'] else None
            fat = float(request.form['fat']) if request.form['fat'] else None
            carbs = float(request.form['carbs']) if request.form['carbs'] else None
            meal_date = datetime.strptime(request.form['meal_date'], '%Y-%m-%d').date()
            meal_time = datetime.strptime(request.form['meal_time'], '%H:%M').time()
            note = request.form.get('note', '')

            meal = Meal(
                user_id=current_user.id,
                meal_type=meal_type,
                food_name=food_name,
                calories=calories,
                protein=protein,
                fat=fat,
                carbs=carbs,
                meal_date=meal_date,
                meal_time=meal_time,
                note=note
            )
            
            db.session.add(meal)
            db.session.commit()
            flash('饮食记录已保存', 'success')
            return redirect(url_for('main.meal_records'))
            
        except ValueError as e:
            flash('请输入有效的数值', 'danger')
        except Exception as e:
            flash('保存失败，请重试', 'danger')
    
    today = date.today().strftime('%Y-%m-%d')
    current_time = datetime.now().strftime('%H:%M')
    return render_template('meal/add.html', today=today, current_time=current_time)

@bp.route('/meal/<int:id>/delete', methods=['POST'])
@login_required
def delete_meal(id):
    meal = Meal.query.get_or_404(id)
    if meal.user_id != current_user.id:
        flash('无权限删除此记录', 'danger')
        return redirect(url_for('main.meal_records'))
    
    db.session.delete(meal)
    db.session.commit()
    flash('记录已删除', 'success')
    return redirect(url_for('main.meal_records'))

@bp.route('/meal/stats')
@login_required
def meal_stats():
    days = request.args.get('days', 7, type=int)
    end_date = date.today()
    start_date = end_date - timedelta(days=days-1)
    
    meals = Meal.query.filter(
        Meal.user_id == current_user.id,
        Meal.meal_date >= start_date,
        Meal.meal_date <= end_date
    ).order_by(Meal.meal_date.asc()).all()
    
    daily_stats = {}
    for meal in meals:
        date_str = meal.meal_date.strftime('%Y-%m-%d')
        if date_str not in daily_stats:
            daily_stats[date_str] = {
                'calories': 0,
                'protein': 0,
                'fat': 0,
                'carbs': 0
            }
        
        if meal.calories:
            daily_stats[date_str]['calories'] += meal.calories
        if meal.protein:
            daily_stats[date_str]['protein'] += meal.protein
        if meal.fat:
            daily_stats[date_str]['fat'] += meal.fat
        if meal.carbs:
            daily_stats[date_str]['carbs'] += meal.carbs
    
    data = {
        'dates': list(daily_stats.keys()),
        'calories': [stats['calories'] for stats in daily_stats.values()],
        'protein': [stats['protein'] for stats in daily_stats.values()],
        'fat': [stats['fat'] for stats in daily_stats.values()],
        'carbs': [stats['carbs'] for stats in daily_stats.values()]
    }
    
    return jsonify(data)

@bp.route('/exercise', methods=['GET'])
@login_required
def exercise_records():
    page = request.args.get('page', 1, type=int)
    per_page = request.args.get('per_page', 10, type=int)
    start_date = request.args.get('start_date', '')
    end_date = request.args.get('end_date', '')
    exercise_type = request.args.get('exercise_type', '')
    sort = request.args.get('sort', 'exercise_date')
    order = request.args.get('order', 'desc')
    
    query = Exercise.query.filter_by(user_id=current_user.id)
    
    if start_date:
        try:
            start = datetime.strptime(start_date, '%Y-%m-%d').date()
            query = query.filter(Exercise.exercise_date >= start)
        except ValueError:
            flash('开始日期格式无效', 'warning')
    
    if end_date:
        try:
            end = datetime.strptime(end_date, '%Y-%m-%d').date()
            query = query.filter(Exercise.exercise_date <= end)
        except ValueError:
            flash('结束日期格式无效', 'warning')
    
    if exercise_type:
        query = query.filter(Exercise.exercise_type == exercise_type)
    
    if sort == 'calories':
        query = query.order_by(Exercise.calories_burned.desc() if order == 'desc' else Exercise.calories_burned.asc())
    elif sort == 'duration':
        query = query.order_by(Exercise.duration.desc() if order == 'desc' else Exercise.duration.asc())
    else:
        query = query.order_by(
            Exercise.exercise_date.desc() if order == 'desc' else Exercise.exercise_date.asc(),
            Exercise.exercise_time.desc() if order == 'desc' else Exercise.exercise_time.asc()
        )
    
    exercises = query.paginate(page=page, per_page=per_page)
    
    return render_template('exercise/records.html',
                         exercises=exercises,
                         start_date=start_date,
                         end_date=end_date,
                         exercise_type=exercise_type,
                         sort=sort,
                         order=order,
                         per_page=per_page)

@bp.route('/exercise/add', methods=['GET', 'POST'])
@login_required
def add_exercise():
    if request.method == 'POST':
        try:
            exercise_type = request.form['exercise_type']
            duration = int(request.form['duration'])
            intensity = request.form['intensity']
            calories_burned = int(request.form['calories_burned']) if request.form['calories_burned'] else None
            distance = float(request.form['distance']) if request.form['distance'] else None
            exercise_date = datetime.strptime(request.form['exercise_date'], '%Y-%m-%d').date()
            exercise_time = datetime.strptime(request.form['exercise_time'], '%H:%M').time()
            note = request.form.get('note', '')

            exercise = Exercise(
                user_id=current_user.id,
                exercise_type=exercise_type,
                duration=duration,
                intensity=intensity,
                calories_burned=calories_burned,
                distance=distance,
                exercise_date=exercise_date,
                exercise_time=exercise_time,
                note=note
            )
            
            db.session.add(exercise)
            db.session.commit()
            flash('运动记录已保存', 'success')
            return redirect(url_for('main.exercise_records'))
            
        except ValueError as e:
            flash('请输入有效的数值', 'danger')
        except Exception as e:
            flash('保存失败，请重试', 'danger')
    
    today = date.today().strftime('%Y-%m-%d')
    current_time = datetime.now().strftime('%H:%M')
    return render_template('exercise/add.html', today=today, current_time=current_time)

@bp.route('/exercise/<int:id>/delete', methods=['POST'])
@login_required
def delete_exercise(id):
    exercise = Exercise.query.get_or_404(id)
    if exercise.user_id != current_user.id:
        flash('无权限删除此记录', 'danger')
        return redirect(url_for('main.exercise_records'))
    
    db.session.delete(exercise)
    db.session.commit()
    flash('记录已删除', 'success')
    return redirect(url_for('main.exercise_records'))

@bp.route('/exercise/stats')
@login_required
def exercise_stats():
    days = request.args.get('days', 7, type=int)
    end_date = date.today()
    start_date = end_date - timedelta(days=days-1)
    
    exercises = Exercise.query.filter(
        Exercise.user_id == current_user.id,
        Exercise.exercise_date >= start_date,
        Exercise.exercise_date <= end_date
    ).order_by(Exercise.exercise_date.asc()).all()
    
    daily_stats = {}
    for exercise in exercises:
        date_str = exercise.exercise_date.strftime('%Y-%m-%d')
        if date_str not in daily_stats:
            daily_stats[date_str] = {
                'duration': 0,
                'calories': 0,
                'distance': 0
            }
        
        daily_stats[date_str]['duration'] += exercise.duration
        if exercise.calories_burned:
            daily_stats[date_str]['calories'] += exercise.calories_burned
        if exercise.distance:
            daily_stats[date_str]['distance'] += exercise.distance
    
    data = {
        'dates': list(daily_stats.keys()),
        'duration': [stats['duration'] for stats in daily_stats.values()],
        'calories': [stats['calories'] for stats in daily_stats.values()],
        'distance': [stats['distance'] for stats in daily_stats.values()]
    }
    
    return jsonify(data)

@bp.route('/settings', methods=['GET', 'POST'])
@login_required
def settings():
    if request.method == 'POST':
        try:
            # 获取表单数据
            height = float(request.form['height']) if request.form['height'] else None
            target_weight = float(request.form['target_weight']) if request.form['target_weight'] else None
            gender = request.form['gender']
            birth_date = datetime.strptime(request.form['birth_date'], '%Y-%m-%d').date() if request.form['birth_date'] else None
            
            # 更新用户信息
            current_user.height = height
            current_user.target_weight = target_weight
            current_user.gender = gender
            current_user.birth_date = birth_date
            
            db.session.commit()
            flash('个人信息已更新', 'success')
            return redirect(url_for('main.settings'))
            
        except ValueError:
            flash('请输入有效的数值', 'danger')
        except Exception as e:
            flash('更新失败，请重试', 'danger')
    
    return render_template('settings/profile.html')

@bp.route('/settings/password', methods=['GET', 'POST'])
@login_required
def change_password():
    if request.method == 'POST':
        try:
            current_password = request.form['current_password']
            new_password = request.form['new_password']
            confirm_password = request.form['confirm_password']
            
            # 验证当前密码
            if not check_password_hash(current_user.password_hash, current_password):
                flash('当前密码不正确', 'danger')
                return redirect(url_for('main.change_password'))
            
            # 验证新密码
            if new_password != confirm_password:
                flash('两次输入的新密码不一致', 'danger')
                return redirect(url_for('main.change_password'))
            
            if len(new_password) < 6:
                flash('新密码长度不能少于6个字符', 'danger')
                return redirect(url_for('main.change_password'))
            
            # 更新密码
            current_user.password_hash = generate_password_hash(new_password)
            db.session.commit()
            flash('密码已更新', 'success')
            return redirect(url_for('main.settings'))
            
        except Exception as e:
            flash('更新失败，请重试', 'danger')
    
    return render_template('settings/password.html') 